const { app, BrowserWindow, ipcMain, Tray, Menu } = require('electron')
const path = require('path')
const isDev = process.env.NODE_ENV === 'development'
const logger = require('./logger')

// 确保应用程序只有一个实例
const gotTheLock = app.requestSingleInstanceLock()

if (!gotTheLock) {
  logger.info('应用程序已经在运行中，退出当前实例')
  app.quit()
} else {
  // 当尝试启动第二个实例时，将激活已有的实例窗口
  app.on('second-instance', (event, commandLine, workingDirectory) => {
    logger.info('检测到第二个实例启动，激活当前窗口')
    // 如果存在窗口实例，则激活它
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore()
      mainWindow.show()
      mainWindow.focus()
    }
  })
}

// 设置应用程序的区域设置为中文，解决乱码问题
app.commandLine.appendSwitch('lang', 'zh-CN')
// 设置字符编码
app.commandLine.appendSwitch('force-chinese-encoding')
// 禁用硬件加速，可能有助于解决某些图形相关的乱码
app.disableHardwareAcceleration()
// 设置磁盘缓存大小，避免缓存错误
app.commandLine.appendSwitch('disk-cache-size', '1')
// 禁用HTTP缓存，避免缓存错误
app.commandLine.appendSwitch('disable-http-cache')

// 保存对托盘的引用，防止被垃圾回收
let tray = null
// 保存对主窗口的引用
let mainWindow = null

function createWindow() {
  logger.info('创建主窗口')
  // 创建浏览器窗口
  mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    frame: false, // 关闭默认工具栏
    icon: isDev ? path.join(__dirname, '../build/icon.ico') : path.join(process.resourcesPath, 'icon.ico'), // 设置应用图标
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: false,
      contextIsolation: true, // 开启上下文隔离以使用contextBridge
      enableRemoteModule: false
    }
  })
  
  // 监听窗口关闭事件，隐藏窗口而不是直接关闭
  mainWindow.on('close', (event) => {
    // 如果是通过托盘菜单的退出选项关闭的，则正常关闭
    if (app.isQuitting) {
      logger.info('应用程序正在退出，关闭主窗口')
      return
    }
    
    // 否则阻止默认行为，隐藏窗口
    logger.info('关闭窗口操作被拦截，窗口已隐藏')
    event.preventDefault()
    mainWindow.hide()
    return false
  })
  
  // 处理窗口控制消息
  ipcMain.on('window-control', (_, command) => {
    logger.info(`接收到窗口控制命令: ${command}`)
    switch (command) {
      case 'minimize':
        mainWindow.minimize()
        break
      case 'maximize':
        if (mainWindow.isMaximized()) {
          mainWindow.unmaximize()
        } else {
          mainWindow.maximize()
        }
        break
      case 'close':
        // 隐藏窗口而不是关闭
        mainWindow.hide()
        break
    }
  })
  
  // 处理渲染进程发送的日志
  ipcMain.on('log', (_, data) => {
    const { level, message, error } = data;
    switch (level) {
      case 'info':
        logger.info(`[渲染进程] ${message}`);
        break;
      case 'warn':
        logger.warn(`[渲染进程] ${message}`);
        break;
      case 'error':
        if (error) {
          logger.error(`[渲染进程] ${message}`, { message: error.message, stack: error.stack });
        } else {
          logger.error(`[渲染进程] ${message}`);
        }
        break;
      default:
        logger.info(`[渲染进程] ${message}`);
    }
  })

  // 加载应用
  if (isDev) {
    // 开发环境下加载本地开发服务器
    logger.info('开发环境: 加载本地开发服务器')
    mainWindow.loadURL('http://localhost:5173')
    // 打开开发工具
    mainWindow.webContents.openDevTools()
  } else {
    // 生产环境下加载打包后的index.html文件
    logger.info('生产环境: 加载打包后的应用')
    mainWindow.loadFile(path.join(__dirname, '../dist/index.html'))
  }
  
  // 监听页面加载完成事件
  mainWindow.webContents.on('did-finish-load', () => {
    logger.info('页面加载完成')
  })
  
  // 监听页面加载失败事件
  mainWindow.webContents.on('did-fail-load', (event, errorCode, errorDescription) => {
    logger.error(`页面加载失败: ${errorDescription} (${errorCode})`)
  })
}

// 创建系统托盘
function createTray() {
  logger.info('创建系统托盘')
  // 托盘图标路径 - Windows系统托盘需要使用ICO格式
  let iconPath;
  if (isDev) {
    // 开发环境使用build目录下的图标
    iconPath = path.join(__dirname, '../build/icon.ico');
  } else {
    // 生产环境使用应用程序目录下的图标
    iconPath = path.join(process.resourcesPath, 'icon.ico');
  }
  
  // 创建托盘实例
  tray = new Tray(iconPath)
  
  // 设置托盘提示文本
  tray.setToolTip('Trans Desktop')
  
  // 创建托盘菜单
  const contextMenu = Menu.buildFromTemplate([
    {
      label: '显示窗口',
      click: () => {
        if (mainWindow) {
          mainWindow.show()
        }
      }
    },
    {
      label: '退出',
      click: () => {
        app.isQuitting = true
        app.quit()
      }
    }
  ])
  
  // 设置托盘上下文菜单
  tray.setContextMenu(contextMenu)
  
  // 点击托盘图标显示窗口
  tray.on('click', () => {
    logger.info('托盘图标被点击，显示主窗口')
    if (mainWindow) {
      mainWindow.show()
    }
  })
}

// 当Electron完成初始化并准备创建浏览器窗口时调用此方法
app.whenReady().then(() => {
  // 只有在获取到单例锁的情况下才创建窗口和托盘
  if (gotTheLock) {
    logger.info('应用程序启动，创建窗口和托盘')
    createWindow()
    createTray()
  }

  app.on('activate', function () {
    // 在macOS上，当点击dock图标并且没有其他窗口打开时，通常会在应用程序中重新创建一个窗口
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// 当所有窗口关闭时退出应用
app.on('window-all-closed', function () {
  // 在macOS上，除非用户使用Cmd + Q确定地退出，否则应用和菜单栏会保持活动状态
  // 对于Windows和Linux，我们也希望应用保持在托盘中运行，除非用户明确退出
  // 因此这里不调用app.quit()
})

// 在应用退出前清理
app.on('before-quit', () => {
  logger.info('应用程序即将退出')
  app.isQuitting = true
})

// 记录应用程序错误
app.on('render-process-gone', (event, webContents, details) => {
  logger.error(`渲染进程崩溃: ${details.reason} (${details.exitCode})`)
})

app.on('child-process-gone', (event, details) => {
  logger.error(`子进程异常退出: ${details.type} (${details.reason})`)
})

// 捕获主进程中的全局未捕获异常
process.on('uncaughtException', (error) => {
  logger.error(`主进程未捕获异常: ${error.message}`, error)
})

// 捕获主进程中的未处理Promise拒绝
process.on('unhandledRejection', (reason, promise) => {
  logger.error(`主进程未处理的Promise拒绝: ${reason}`, reason instanceof Error ? reason : new Error(String(reason)))
})

// 监听渲染进程的错误事件
app.on('web-contents-created', (_, contents) => {
  contents.on('did-fail-load', (event, errorCode, errorDescription) => {
    logger.error(`页面加载失败: ${errorDescription} (${errorCode})`)
  })
  
  contents.on('crashed', (event, killed) => {
    logger.error(`渲染进程崩溃: ${killed ? '被系统终止' : '自行崩溃'}`)
  })
  
  contents.on('console-message', (event, level, message, line, sourceId) => {
    if (level === 2) { // 错误级别
      logger.error(`渲染进程控制台错误: ${message} (${sourceId}:${line})`)
    }
  })
})
